package com.ss.service.support;

import com.ss.core.exceptions.SummerExecuteException;
import com.ss.entity.*;
import com.ss.mapper.SummerAppointMemberGlobalMapper;
import com.ss.mapper.SummerAppointMemberMapper;
import com.ss.mapper.SummerGroupMemberMapper;
import com.ss.utlis.ListUtil;

import java.util.ArrayList;
import java.util.List;

/**
 * 指定审核人的工具类
 * @Author: 夏十七
 * @Date: 2019/8/14 21:07
 * @Version 1.0
 */
public class SummerAppoint {

    private SummerInstance instance;
    private String errorMsg;
    private SummerAppointMemberMapper summerAppointMemberMapper;
    private SummerAppointMemberGlobalMapper summerAppointMemberGlobalMapper;
    private ExecuteMember executeMember;

    /**
     * 私有的构造器
     * @param instance 审核实例
     * @param errorMsg 错误信息 ， 如果有值则不能使用这个功能
     * @param summerAppointMemberMapper sql
     * @param summerAppointMemberGlobalMapper sql
     * @param executeMember sql
     */
    private SummerAppoint(SummerInstance instance,String errorMsg,SummerAppointMemberMapper summerAppointMemberMapper,SummerAppointMemberGlobalMapper summerAppointMemberGlobalMapper,ExecuteMember executeMember){
        this.instance = instance;
        this.errorMsg = errorMsg;
        this.summerAppointMemberGlobalMapper = summerAppointMemberGlobalMapper;
        this.summerAppointMemberMapper = summerAppointMemberMapper;
        this.executeMember = executeMember;
    }

    /**
     * 静态方法，获取工具类唯一途径
     * @param instance 审核实例
     * @param errorMsg 错误信息 ， 如果有值则不能使用这个功能
     * @param summerAppointMemberMapper sql
     * @param summerAppointMemberGlobalMapper sql
     * @param executeMember sql
     * @return
     */
    public static SummerAppoint of(SummerInstance instance,String errorMsg,SummerAppointMemberMapper summerAppointMemberMapper,SummerAppointMemberGlobalMapper summerAppointMemberGlobalMapper,ExecuteMember executeMember){
        return new SummerAppoint(instance,errorMsg,summerAppointMemberMapper,summerAppointMemberGlobalMapper,executeMember);
    }


    /**
     * 通过组指定审核人 -- 指定下个节点
     * @param groupId 组-> 源id sourceId
     */
    public void appointGroup(String groupId){
        init();
        //获取指定审核人
        List<SummerGroupMember> groupMemberList = executeMember.getMemberBySourceId(groupId);
        //获取节点审核人
        List<SummerNodeMember> nodeMemberList = executeMember.getNodeMemberByNodeId(instance.getNowNode());
        ArrayList<SummerAppointMember> appointMembers = new ArrayList<>();
        //去掉组查询出来的审核人不再流审核人列表中的数据
        for (SummerNodeMember summerNodeMember : nodeMemberList) {
            //判断审核人列表数据在不再指定人列表中，不再不添加
            boolean z = ListUtil.contains(groupMemberList,
                    e->e.getMemberId().equals(summerNodeMember.getMemberId()));
            if (z){
                SummerAppointMember appointMember = new SummerAppointMember();
                appointMember.setNodeId(instance.getNowNode());
                appointMember.setMemberId(summerNodeMember.getMemberId());
                appointMember.setInstanceId(instance.getId());
                appointMembers.add(appointMember);
            }
        }
        if (appointMembers.size()==0){
            throw new SummerExecuteException("指定审核人时未指定任何一个人");
        }
        //保存数据库
        summerAppointMemberMapper.insertAll(appointMembers);
    }

    /**
     * 通过组全局指定审核人，一般作为提交时指定
     * @param groupId 组-> 源id sourceId
     */
    public void appointGroupForGlobal(String groupId){
        init();
        //获取指定审核人
        List<SummerGroupMember> groupMemberList = executeMember.getMemberBySourceId(groupId);
        //获取所有节点审核人
        List<SummerNodeMember> nodeMemberList = executeMember.getNodeMemberByFlowId(instance.getFlowId());
        ArrayList<SummerAppointMemberGlobal> appointMemberGlobals = new ArrayList<>();
        //去掉组查询出来的审核人不再流审核人列表中的数据
        for (SummerNodeMember summerNodeMember : nodeMemberList) {
            //判断审核人列表数据在不再指定人列表中，不再不添加
            boolean z = ListUtil.contains(groupMemberList,
                    e->e.getMemberId().equals(summerNodeMember.getMemberId()));
            if (z){
                SummerAppointMemberGlobal appointMemberGlobal = new SummerAppointMemberGlobal();
                appointMemberGlobal.setMemberId(summerNodeMember.getMemberId());
                appointMemberGlobal.setInstanceId(instance.getId());
                appointMemberGlobals.add(appointMemberGlobal);
            }
        }
        if (appointMemberGlobals.size()==0){
            throw new SummerExecuteException("指定审核人时未指定任何一个人");
        }
        //保存数据库
        summerAppointMemberGlobalMapper.insertAll(appointMemberGlobals);
    }

    /**
     * 指定下个节点审核人
     * @param members 审核人Id
     */
    public void appointMembers(String ... members){
        init();
        if (members.length == 0){
            throw new SummerExecuteException("指定审核人时未指定任何一个人");
        }
        executeMember.contain(instance.getNowNode(),members);
        //指定审核人
        ArrayList<SummerAppointMember> list = new ArrayList<>();
        for (String member : members) {
            SummerAppointMember summerAppointMember = new SummerAppointMember();
            summerAppointMember.setInstanceId(instance.getId());
            summerAppointMember.setMemberId(member);
            summerAppointMember.setNodeId(instance.getNowNode());
            list.add(summerAppointMember);
        }
        summerAppointMemberMapper.insertAll(list);
    }

    /**
     * 全局指定审核人 ，一般作为提交时
     * @param members 审核人Id
     */
    public void appointMembersForGlobal(String ... members){
        init();
        if (members.length == 0){
            throw new SummerExecuteException("指定审核人时未指定任何一个人");
        }
        executeMember.containByFlow(instance.getId(),members);
        //指定审核人
        ArrayList<SummerAppointMemberGlobal> appointMemberGlobals = new ArrayList<>();
        for (String member : members) {
            SummerAppointMemberGlobal appointMemberGlobal = new SummerAppointMemberGlobal();
            appointMemberGlobal.setMemberId(member);
            appointMemberGlobal.setInstanceId(instance.getId());
            appointMemberGlobals.add(appointMemberGlobal);
        }
        summerAppointMemberGlobalMapper.insertAll(appointMemberGlobals);
    }

    /**
     * 检测实例当前节点是否可以指定审核人
     */
    private void init(){
        if (errorMsg != null){
            throw new SummerExecuteException(errorMsg);
        }
    }



}
